#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
TCP数据控制器

实现HTTP API路由，处理EEG数据的上传、查询和版本控制请求。
"""

from fastapi import APIRouter, HTTPException, Query, Path, Depends
from fastapi.responses import JSONResponse
from typing import Optional, Dict, Any
import logging
from datetime import datetime

from service.tcp_data_service import (
    get_tcp_data_service, 
    TCPDataService,
    EEGDataRequest,
    EEGDataResponse,
    RealtimeDataResponse,
    VersionCheckResponse
)

logger = logging.getLogger(__name__)

# 创建路由器
router = APIRouter(prefix="/api/eeg", tags=["EEG数据"])


@router.post("/upload", 
            response_model=EEGDataResponse,
            summary="上传EEG数据",
            description="接收来自APK设备的EEG数据并存储到数据库和内存缓存")
async def upload_eeg_data(
    request: EEGDataRequest,
    tcp_service: TCPDataService = Depends(get_tcp_data_service)
) -> EEGDataResponse:
    """
    上传EEG数据
    
    接收来自APK设备的EEG数据，进行验证后存储到数据库和内存缓存中。
    
    Args:
        request: EEG数据上传请求
        tcp_service: TCP数据服务依赖注入
        
    Returns:
        上传结果响应
        
    Raises:
        HTTPException: 数据验证失败或存储失败
    """
    try:
        logger.info(f"收到EEG数据上传请求 - 房间: {request.room_id}, 会话: {request.session_id}, 序列: {request.sequence}")
        
        # 调用服务层处理数据上传
        response = await tcp_service.upload_eeg_data(request)
        
        logger.info(f"EEG数据上传成功 - 房间: {request.room_id}, 版本: {response.version}")
        return response
        
    except ValueError as e:
        logger.warning(f"数据验证失败 - 房间: {request.room_id}, 错误: {e}")
        raise HTTPException(status_code=400, detail=f"数据验证失败: {str(e)}")
    except Exception as e:
        logger.error(f"数据上传失败 - 房间: {request.room_id}, 错误: {e}")
        raise HTTPException(status_code=500, detail=f"服务器内部错误: {str(e)}")


@router.get("/realtime/{room_id}",
           response_model=RealtimeDataResponse,
           summary="获取实时数据",
           description="获取指定房间的实时EEG数据，支持时间范围查询")
async def get_realtime_data(
    room_id: str = Path(..., description="房间ID", min_length=1, max_length=50),
    since: Optional[float] = Query(None, description="起始时间戳(Unix时间戳)", ge=0),
    limit: Optional[int] = Query(None, description="最大返回条数", ge=1, le=1000),
    tcp_service: TCPDataService = Depends(get_tcp_data_service)
) -> RealtimeDataResponse:
    """
    获取实时EEG数据
    
    返回指定房间的最新EEG数据，可选择性地返回指定时间戳之后的历史数据。
    
    Args:
        room_id: 房间ID
        since: 起始时间戳，返回该时间之后的数据
        limit: 最大返回条数
        tcp_service: TCP数据服务依赖注入
        
    Returns:
        实时数据响应
        
    Raises:
        HTTPException: 查询失败
    """
    try:
        logger.debug(f"收到实时数据查询请求 - 房间: {room_id}, since: {since}, limit: {limit}")
        
        # 调用服务层获取实时数据
        response = await tcp_service.get_realtime_data(room_id, since, limit)
        
        logger.debug(f"实时数据查询成功 - 房间: {room_id}, 版本: {response.version}")
        return response
        
    except Exception as e:
        logger.error(f"实时数据查询失败 - 房间: {room_id}, 错误: {e}")
        raise HTTPException(status_code=500, detail=f"查询失败: {str(e)}")


@router.get("/version/{room_id}",
           response_model=VersionCheckResponse,
           summary="检查数据版本",
           description="检查指定房间的数据版本，用于客户端轮询优化")
async def check_data_version(
    room_id: str = Path(..., description="房间ID", min_length=1, max_length=50),
    client_version: Optional[int] = Query(None, description="客户端当前版本号", ge=0),
    tcp_service: TCPDataService = Depends(get_tcp_data_service)
) -> VersionCheckResponse:
    """
    检查数据版本
    
    返回指定房间的当前数据版本号，客户端可以用此接口优化轮询策略。
    
    Args:
        room_id: 房间ID
        client_version: 客户端当前版本号，用于判断是否有新数据
        tcp_service: TCP数据服务依赖注入
        
    Returns:
        版本检查响应
        
    Raises:
        HTTPException: 查询失败
    """
    try:
        logger.debug(f"收到版本检查请求 - 房间: {room_id}, 客户端版本: {client_version}")
        
        # 调用服务层检查版本
        response = await tcp_service.check_version(room_id, client_version)
        
        logger.debug(f"版本检查完成 - 房间: {room_id}, 当前版本: {response.version}, 有新数据: {response.has_new_data}")
        return response
        
    except Exception as e:
        logger.error(f"版本检查失败 - 房间: {room_id}, 错误: {e}")
        raise HTTPException(status_code=500, detail=f"版本检查失败: {str(e)}")


@router.get("/status/{room_id}",
           summary="获取房间状态",
           description="获取指定房间的详细状态信息")
async def get_room_status(
    room_id: str = Path(..., description="房间ID", min_length=1, max_length=50),
    tcp_service: TCPDataService = Depends(get_tcp_data_service)
) -> Dict[str, Any]:
    """
    获取房间状态
    
    返回指定房间的详细状态信息，包括缓存状态、活跃会话等。
    
    Args:
        room_id: 房间ID
        tcp_service: TCP数据服务依赖注入
        
    Returns:
        房间状态信息
        
    Raises:
        HTTPException: 查询失败
    """
    try:
        logger.debug(f"收到房间状态查询请求 - 房间: {room_id}")
        
        # 调用服务层获取房间状态
        status = await tcp_service.get_room_status(room_id)
        
        logger.debug(f"房间状态查询成功 - 房间: {room_id}")
        return status
        
    except Exception as e:
        logger.error(f"房间状态查询失败 - 房间: {room_id}, 错误: {e}")
        raise HTTPException(status_code=500, detail=f"状态查询失败: {str(e)}")


@router.get("/metrics",
           summary="获取服务指标",
           description="获取TCP数据服务的性能指标和统计信息")
async def get_service_metrics(
    tcp_service: TCPDataService = Depends(get_tcp_data_service)
) -> Dict[str, Any]:
    """
    获取服务性能指标
    
    返回TCP数据服务的详细性能指标，包括请求统计、响应时间、缓存命中率等。
    
    Args:
        tcp_service: TCP数据服务依赖注入
        
    Returns:
        服务性能指标
    """
    try:
        logger.debug("收到服务指标查询请求")
        
        # 获取服务指标
        metrics = tcp_service.get_service_metrics()
        
        logger.debug("服务指标查询成功")
        return metrics
        
    except Exception as e:
        logger.error(f"服务指标查询失败: {e}")
        raise HTTPException(status_code=500, detail=f"指标查询失败: {str(e)}")


@router.post("/batch/upload",
            summary="批量上传EEG数据",
            description="批量上传多条EEG数据，提高传输效率")
async def batch_upload_eeg_data(
    requests: list[EEGDataRequest],
    tcp_service: TCPDataService = Depends(get_tcp_data_service)
) -> Dict[str, Any]:
    """
    批量上传EEG数据
    
    接收多条EEG数据进行批量处理，提高传输效率。
    
    Args:
        requests: EEG数据上传请求列表
        tcp_service: TCP数据服务依赖注入
        
    Returns:
        批量上传结果
        
    Raises:
        HTTPException: 批量处理失败
    """
    if not requests:
        raise HTTPException(status_code=400, detail="请求列表不能为空")
    
    if len(requests) > 100:  # 限制批量大小
        raise HTTPException(status_code=400, detail="批量大小不能超过100条")
    
    try:
        logger.info(f"收到批量EEG数据上传请求 - 数量: {len(requests)}")
        
        results = []
        success_count = 0
        error_count = 0
        
        # 逐个处理每条数据
        for i, request in enumerate(requests):
            try:
                response = await tcp_service.upload_eeg_data(request)
                results.append({
                    'index': i,
                    'room_id': request.room_id,
                    'status': 'success',
                    'version': response.version,
                    'message': response.message
                })
                success_count += 1
            except Exception as e:
                results.append({
                    'index': i,
                    'room_id': request.room_id,
                    'status': 'error',
                    'error': str(e)
                })
                error_count += 1
                logger.warning(f"批量上传中第{i}条数据失败 - 房间: {request.room_id}, 错误: {e}")
        
        logger.info(f"批量上传完成 - 成功: {success_count}, 失败: {error_count}")
        
        return {
            'total': len(requests),
            'success_count': success_count,
            'error_count': error_count,
            'results': results,
            'timestamp': datetime.now().isoformat()
        }
        
    except Exception as e:
        logger.error(f"批量上传失败: {e}")
        raise HTTPException(status_code=500, detail=f"批量处理失败: {str(e)}")


@router.get("/rooms",
           summary="获取活跃房间列表",
           description="获取当前有数据的房间列表")
async def get_active_rooms(
    tcp_service: TCPDataService = Depends(get_tcp_data_service)
) -> Dict[str, Any]:
    """
    获取活跃房间列表
    
    返回当前内存缓存中有数据的房间列表及其基本信息。
    
    Args:
        tcp_service: TCP数据服务依赖注入
        
    Returns:
        活跃房间列表
    """
    try:
        logger.debug("收到活跃房间列表查询请求")
        
        # 获取缓存统计信息
        cache_stats = tcp_service.memory_cache.get_cache_stats()
        
        # 获取所有房间的基本信息
        rooms = []
        for room_id in tcp_service.memory_cache.latest_data.keys():
            room_info = tcp_service.memory_cache.get_room_info(room_id)
            rooms.append(room_info)
        
        logger.debug(f"活跃房间列表查询成功 - 房间数: {len(rooms)}")
        
        return {
            'total_rooms': len(rooms),
            'rooms': rooms,
            'cache_stats': cache_stats,
            'timestamp': datetime.now().isoformat()
        }
        
    except Exception as e:
        logger.error(f"活跃房间列表查询失败: {e}")
        raise HTTPException(status_code=500, detail=f"查询失败: {str(e)}")


@router.delete("/cache/{room_id}",
              summary="清除房间缓存",
              description="清除指定房间的内存缓存数据")
async def clear_room_cache(
    room_id: str = Path(..., description="房间ID", min_length=1, max_length=50),
    tcp_service: TCPDataService = Depends(get_tcp_data_service)
) -> Dict[str, Any]:
    """
    清除房间缓存
    
    清除指定房间在内存缓存中的所有数据，不影响数据库中的数据。
    
    Args:
        room_id: 房间ID
        tcp_service: TCP数据服务依赖注入
        
    Returns:
        清除结果
    """
    try:
        logger.info(f"收到清除房间缓存请求 - 房间: {room_id}")
        
        # 清除房间缓存
        success = tcp_service.memory_cache.clear_room_cache(room_id)
        
        if success:
            logger.info(f"房间缓存清除成功 - 房间: {room_id}")
            return {
                'status': 'success',
                'room_id': room_id,
                'message': '房间缓存已清除',
                'timestamp': datetime.now().isoformat()
            }
        else:
            logger.warning(f"房间缓存不存在 - 房间: {room_id}")
            return {
                'status': 'not_found',
                'room_id': room_id,
                'message': '房间缓存不存在',
                'timestamp': datetime.now().isoformat()
            }
        
    except Exception as e:
        logger.error(f"清除房间缓存失败 - 房间: {room_id}, 错误: {e}")
        raise HTTPException(status_code=500, detail=f"清除失败: {str(e)}")


@router.post("/cache/cleanup",
            summary="手动清理过期缓存",
            description="手动触发过期缓存清理任务")
async def manual_cache_cleanup(
    tcp_service: TCPDataService = Depends(get_tcp_data_service)
) -> Dict[str, Any]:
    """
    手动清理过期缓存
    
    手动触发缓存清理任务，清除过期的房间数据和时间窗口数据。
    
    Args:
        tcp_service: TCP数据服务依赖注入
        
    Returns:
        清理结果
    """
    try:
        logger.info("收到手动缓存清理请求")
        
        # 执行缓存清理
        cleaned_count = tcp_service.memory_cache.cleanup_expired_data()
        
        logger.info(f"手动缓存清理完成 - 清理了 {cleaned_count} 条数据")
        
        return {
            'status': 'success',
            'cleaned_count': cleaned_count,
            'message': f'已清理 {cleaned_count} 条过期数据',
            'timestamp': datetime.now().isoformat()
        }
        
    except Exception as e:
        logger.error(f"手动缓存清理失败: {e}")
        raise HTTPException(status_code=500, detail=f"清理失败: {str(e)}")


# 健康检查端点
@router.get("/health",
           summary="健康检查",
           description="检查TCP数据服务的健康状态")
async def health_check(
    tcp_service: TCPDataService = Depends(get_tcp_data_service)
) -> Dict[str, Any]:
    """
    健康检查
    
    返回TCP数据服务的健康状态信息。
    
    Args:
        tcp_service: TCP数据服务依赖注入
        
    Returns:
        健康状态信息
    """
    try:
        # 获取服务指标
        metrics = tcp_service.get_service_metrics()
        
        # 检查服务状态
        is_healthy = True
        health_issues = []
        
        # 检查错误率
        if metrics['error_rate'] > 0.1:  # 错误率超过10%
            is_healthy = False
            health_issues.append(f"错误率过高: {metrics['error_rate']:.2%}")
        
        # 检查响应时间
        if metrics['avg_upload_time'] > 1.0:  # 上传时间超过1秒
            is_healthy = False
            health_issues.append(f"上传响应时间过长: {metrics['avg_upload_time']:.3f}s")
        
        # 检查内存使用
        cache_stats = metrics['cache_stats']
        memory_usage = cache_stats['memory_usage']
        if memory_usage.percent > 90:  # 内存使用超过90%
            is_healthy = False
            health_issues.append(f"内存使用率过高: {memory_usage.percent:.1f}%")
        
        # 计算缓存命中率
        cache_metrics = cache_stats['metrics']
        total_cache_requests = cache_metrics.get('cache_hits', 0) + cache_metrics.get('cache_misses', 0)
        cache_hit_rate = cache_metrics.get('cache_hits', 0) / total_cache_requests if total_cache_requests > 0 else 0.0
        
        status = "healthy" if is_healthy else "unhealthy"
        
        return {
            'status': status,
            'is_healthy': is_healthy,
            'uptime_seconds': metrics['uptime_seconds'],
            'total_requests': metrics['upload_count'] + metrics['query_count'],
            'error_rate': metrics['error_rate'],
            'cache_hit_rate': cache_hit_rate,
            'memory_usage_percent': memory_usage.percent,
            'health_issues': health_issues,
            'timestamp': datetime.now().isoformat()
        }
        
    except Exception as e:
        logger.error(f"健康检查失败: {e}")
        return {
            'status': 'error',
            'is_healthy': False,
            'error': str(e),
            'timestamp': datetime.now().isoformat()
        }